const canvasDom = document.getElementById("canvas"),
      temperatureDom = document.getElementById("temperature"),
      fanSpeedDom = document.getElementById("fan-speed"),
      fanPictureDom = document.getElementById("fan-picture"),
      heatingFlowDom = document.getElementById("heating-flow"),
      heatingPictureDom = document.getElementById("heating-picture"),
      targetTemperatureInputDom = document.getElementById("target-temperature");

canvasDom.width = window.innerWidth;
canvasDom.height = 800;

let temperature = 2000,  //当前温度
    targetTemperature = 2500;  //目标温度

/**
 * 温度爬升模拟
 */
setInterval(() => {
    temperature += parseInt(Math.random() * 100)
}, 500);

/**
 * 风扇降温模拟
 */
let fanSpeed = 0;
setInterval(() => {
    temperature -= 1 * fanSpeed;
}, 500);

/**
 * 暖气升温模拟
 */
 let heatingFlow = 0;
 setInterval(() => {
     temperature += 1 * heatingFlow;
 }, 500);

/**
 * PID算法
 */
const Proportion = 200,  //比例常数
      Integral = 1,  //积分常数
      Derivative = 90  //微分常数
let prevOffset = 0,
    lastOffset = 0,
    sumOffset = 0;
function pidCalc(nextPoint, setPoint) {
    const offset = setPoint - nextPoint;
    sumOffset += offset;
    differOffset = lastOffset - prevOffset;
    prevOffset = lastOffset;
    lastOffset = offset;
    return Proportion * offset + Integral * sumOffset + Derivative * differOffset;
}

const temperatureStack = [temperature];
const ctx = canvasDom.getContext("2d");
let height = 500;
setInterval(() => {
    if(temperatureStack.length >= Math.ceil(canvas.width / 5))
        temperatureStack.shift();
    temperatureStack.push(temperature);
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.beginPath();
    ctx.strokeStyle = "#888";
    ctx.lineWidth = 1;
    const standard = -(targetTemperature / 100 * 2) + height;
    ctx.moveTo(0, standard);
    ctx.lineTo(canvas.width, standard);
    ctx.stroke();
    ctx.strokeStyle = "red";
    ctx.lineWidth = 2;
    let lastX = 0,
        lastY = height;
    ctx.beginPath();
    for(let i = 0;i < temperatureStack.length;i++) {
        lastX = i * 5;
        lastY = -(temperatureStack[i] / 100 * 2) + height;
        ctx.lineTo(lastX, lastY);
    }
    ctx.stroke();
}, 100);

setInterval(() => {
    temperatureDom.innerHTML = `${(temperature / 100).toFixed(2)}℃`;
    const result = pidCalc(temperature, targetTemperature);
    if(result > 0) {
        fanSpeed = 0;
        fanSpeedDom.innerHTML = "0";
        fanPictureDom.style.animationDuration = `${0}ms`;
    }
    else {
        fanSpeed = (-result) / 1000;
        fanSpeedDom.innerHTML = `${fanSpeed.toFixed(2)}`;
        fanPictureDom.style.animationDuration = `${500 - fanSpeed * 0.6}ms`;
    }
    const result2 = pidCalc(temperature, targetTemperature);
    if(result2 <= 0) {
        heatingFlow = 0;
        heatingFlowDom.innerHTML = "0";
        heatingPictureDom.style.animationDuration = `${0}ms`;
    }
    else {
        heatingFlow = result2 / 1000;
        heatingFlowDom.innerHTML = `${heatingFlow.toFixed(2)}`;
        heatingPictureDom.style.animationDuration = `${500 - heatingFlow * 0.6}ms`;
    }
}, 100);

function setTargetTemperature() {
    targetTemperature = targetTemperatureInputDom.value * 100;
}

function cool() {
    temperature -= 1000;
    prevOffset = 0;
    lastOffset = 0;
    sumOffset = 0;
}

function hold() {
    temperature += 1000;
    prevOffset = 0;
    lastOffset = 0;
    sumOffset = 0;
}